# -*- coding: utf-8 -*-
# @File     : services.py
# @Author   : bingjia
# @Time     : 2020/8/4 17:56
# @Desc     : permission服务

from django.apps import apps

from .choice import ADMINS_PERMISSIONS, MEMBERS_PERMISSIONS


def _get_object_project(obj):
    """
    获取对象
    """
    project = None
    Project = apps.get_model("projects", "Project")
    if isinstance(obj, Project):
        project = obj
    elif obj and hasattr(obj, 'project'):
        project = obj.project
    return project


def _get_user_project_membership(user, project, cache="user"):
    """
    cache param determines how memberships are calculated trying to reuse the existing data
    in cache
    """
    if user.is_anonymous:
        return None

    if cache == "user":
        return user.cached_membership_for_project(project)

    return project.cached_memberships_for_user(user)


def is_project_owner(user, obj):
    """
    判断对象的拥有者
    :param user:
    :param obj:
    :return:
    """
    project = _get_object_project(obj)
    if project is None:
        return False
    if user.id == project.owner_id:
        return True

    return False


def _get_membership_permissions(membership):
    if membership and membership.role and membership.role.permissions:
        return membership.role.permissions
    return []


def calculate_permissions(is_superuser=False, is_member=False,
                          is_admin=False, role_permissions=[]):
    if is_superuser:
        admins_permissions = list(map(lambda perm: perm[0], ADMINS_PERMISSIONS))
        members_permissions = list(map(lambda perm: perm[0], MEMBERS_PERMISSIONS))
    elif is_member:
        if is_admin:
            admins_permissions = list(map(lambda perm: perm[0], ADMINS_PERMISSIONS))
            members_permissions = list(map(lambda perm: perm[0], MEMBERS_PERMISSIONS))
        else:
            admins_permissions = []
            members_permissions = []
        members_permissions = members_permissions + role_permissions
    else:
        admins_permissions = []
        members_permissions = []

    return set(admins_permissions + members_permissions)


def get_user_project_permissions(user, project, cache="user"):
    """
    获取用户对项目的权限
    """
    membership = _get_user_project_membership(user, project, cache=cache)
    is_member = membership is not None
    is_admin = is_member and membership.is_admin
    return calculate_permissions(
        is_superuser=user.is_superuser,
        is_member=is_member,
        is_admin=is_admin,
        role_permissions=_get_membership_permissions(membership),
    )


def is_project_admin(user, obj):
    if user.is_superuser:
        return True

    project = _get_object_project(obj)
    if project is None:
        return False

    membership = _get_user_project_membership(user, project)
    if membership and membership.is_admin:
        return True

    return False


def user_has_perm(user, perm, obj=None, cache="user"):
    """
    cache param determines how memberships are calculated trying to reuse the existing data
    in cache
    """
    project = _get_object_project(obj)
    if not project:
        return False

    return perm in get_user_project_permissions(user, project, cache=cache)